#pragma once

/*
DoomsdayDate algorithm implementation is taken from http://www.codeproject.com/KB/datetime/doomsdaydate.aspx
Many thanks to Paul J. Weiss.
*/

namespace TimeZone
{
	enum Day
	{
		InvalidDay		= -1
	};

	enum Weekday
	{
		Sunday			= 0,
		Monday			= 1,
		Tuesday			= 2,
		Wednesday		= 3,
		Thursday		= 4,
		Friday			= 5,
		Saturday		= 6,
		InvalidWeekday	= -1
	};

	enum Month
	{
		Jan				= 1,
		Feb				= 2,
		Mar				= 3,
		Apr				= 4,
		May				= 5,
		Jun				= 6,
		Jul				= 7,
		Aug				= 8,
		Sep				= 9,
		Oct				= 10,
		Nov				= 11,
		Dec				= 12,
		InvalidMonth	= -1
	};

	enum Year
	{
		InvalidYear		= -1
	};

	class DoomsdayDate
	{
		Month	m_month;
		int		m_day;
		int		m_year;
		Weekday	m_weekday;
		bool	m_ad;
		bool	m_gregorian;
		bool	m_valid;
		bool	m_useJulianBeforeGregorian;

		int		DoomsdayCentury(int century);
		int		DoomsdayMonth(Month month);
		bool	Gregorian(int month, int day, int year);
		bool	LeapYear(int year);

	public:

		//-----------------------------------------------------
		// JulianBeforeGregorian refers to the weird dates
		// between October 5-14, 1582 which were deleted from
		// the Gregorian calendar.  Technically the days never
		// existed.  The default is false which sets the date
		// as invalid.  
		//-----------------------------------------------------
		DoomsdayDate(bool JulianBeforeGregorian = true);
		DoomsdayDate(int month, int day, int year, bool ad=true);

		bool Set(int month, int day, int year, bool ad=true);
		Weekday weekday();    
		int sundayDay(int nth_sunday_in_month); // returns the day of n-th sunday in month
		int daysInMonth(void);
	};
} // namespace TimeZone